package com.sc.nft.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.google.common.collect.Lists;
import com.sc.nft.dao.*;
import com.sc.nft.dto.MetaMapSettleDTO;
import com.sc.nft.entity.*;
import com.sc.nft.entity.dto.SupplierManagePageVO;
import com.sc.nft.enums.*;
import com.sc.nft.enums.task.ActivityTypeEnum;
import com.sc.nft.enums.wallet.MallDaoWalletTypeEnum;
import com.sc.nft.exception.GlobalException;
import com.sc.nft.exception.GlobalRunTimeException;
import com.sc.nft.feign.WxMiniProfitTemplateClient;
import com.sc.nft.feign.WxMiniUserPointsClient;
import com.sc.nft.helper.MessageQueueHelper;
import com.sc.nft.req.profittemplate.ProfitTemplateGetProfitAndPointsReq;
import com.sc.nft.service.*;
import com.sc.nft.sup.ErrorCode;
import com.sc.nft.util.BigDecimalUtils;
import com.sc.nft.util.LocalDateTimeUtil;
import com.sc.nft.vo.profittemplate.ProfitTemplateGetProfitAndPointsVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionSynchronizationAdapter;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class MallOrderIncomeImpl implements MallOrderIncomeService {

    private final MallIncomeService mallIncomeService;
    private final UserCollectionService userCollectionService;
    private final UserInfoDao userInfoDao;
    private final UserCityServerCentreDao userCityServerCentreDao;
    private final MallOrderIncomeDao mallOrderIncomeDao;
    private final UserWalletDao userWalletDao;
    private final MallOrderService mallOrderService;
    private final UserWorkRoomDao userWorkRoomDao;
    private final MallOrderProductService mallOrderProductService;
    private final CarveUpPoolService carveUpPoolService;
    private final NftRegionBindingDao nftRegionBindingDao;
    private final UserCollectionDao userCollectionDao;
    private final UserWalletDetailDao userWalletDetailDao;
    private final ExpenditureRecordService expenditureRecordService;
    private final SupplierManageDao supplierManageDao;
    private final SupplierManageBindingDao supplierManageBindingDao;
    private final MallOrderRefundService mallOrderRefundService;
    private final MallActivitySpecsService mallActivitySpecsService;
    private final MallProfitTemplateService mallProfitTemplateService;
    private final StaticDataDao staticDataDao;
    private final UserCreatorInfoService userCreatorInfoService;
    private final MallDaoWalletService mallDaoWalletService;
    private final MallRankingListPoolService mallRankingListPoolService;
    private final WxMiniProfitTemplateClient wxMiniProfitTemplateClient;
    private final WxMiniUserPointsClient wxMiniUserPointsClient;
    private final WxMiniUserInfoDao wxMiniUserInfoDao;
    private final MessageQueueHelper messageQueueHelper;
    private final MetaMapSettleDao metaMapSettleDao;

    @Override
    public void calculateIncome(List<MallOrderProduct> orderProdcutList, MallOrder mallOrder, UserInfo user) {


        //总售价
        BigDecimal sumProductSalesPrice = BigDecimal.ZERO;
        //总成本价
        BigDecimal sumproductCostPrice = BigDecimal.ZERO;

        BigDecimal couponAmount = BigDecimal.ZERO;
        if (Objects.nonNull(mallOrder.getCouponAmount())) {
            couponAmount = mallOrder.getCouponAmount();
        }
        for (MallOrderProduct mallOrderProduct : orderProdcutList) {
            BigDecimal singleSalesPrice = mallOrderProduct.getProductSalesPrice().multiply(Convert.toBigDecimal(mallOrderProduct.getProductNum()));
            sumProductSalesPrice = sumProductSalesPrice.add(singleSalesPrice);
            // 总成本
            BigDecimal singleCostPrice = BigDecimalUtils.add(mallOrderProduct.getProductCostPrice(), mallOrderProduct.getActivityCostPrice(), mallOrderProduct.getReservePrice()).multiply(Convert.toBigDecimal(mallOrderProduct.getProductNum()));
            sumproductCostPrice = sumproductCostPrice.add(singleCostPrice);

        }
        //计算收益
        List<MallIncome> list = mallIncomeService.getIncomeListByDaoId(mallOrder.getDaoId());
        //总利润 计算收益金额
        BigDecimal sumProfit = sumProductSalesPrice.subtract(sumproductCostPrice).subtract(couponAmount);
        /* 2023-10-13 4.5.0版本需求.新增两个收益,收益名字为地图收益和供应商推荐收益*/
        if (BigDecimalUtils.compareTo(BigDecimal.ZERO, sumProfit)) {
            // 利润小于等于0 不分
            return;
        }

        for (MallOrderProduct mallOrderProduct : orderProdcutList) {
            // 供应商收益.
            List<MallIncome> supplyChain = list.stream()
                    .filter(mallIncome -> mallIncome.getIncomeType() == IncomeTypeEnum.SUPPLY_CHAIN)
                    .sorted(Comparator.comparing(MallIncome::getIncomeProportion).reversed())
                    .collect(Collectors.toList());
            if (CollUtil.isNotEmpty(supplyChain)) {
                for (MallIncome mallIncome : supplyChain) {
                    // 根据产品的id获取供应商对应的推荐人.对他进行分钱.
                    SupplierManageBinding mallId = supplierManageBindingDao.getMallId(mallOrderProduct.getProductId());
                    if (BeanUtil.isEmpty(mallId)) {
                        break;
                    }
                    SupplierManagePageVO byId = supplierManageDao.getById(mallId.getSupplierId());
                    if (BeanUtil.isEmpty(byId)) {
                        break;
                    }
                    if (byId.getUserId() == null) {
                        break;
                    }
                    // 商城收益人进行处理.

                    // 幂等性效验
                    MallOrderIncome incomeUserIdAndIncomeTypeAndOrderId = getOneByIncomeUserIdAndIncomeTypeAndOrderId(byId.getUserId(), IncomeTypeEnum.SUPPLY_CHAIN, mallOrder.getId());
                    if (ObjectUtil.isNotNull(incomeUserIdAndIncomeTypeAndOrderId)) {
                        return;
                    }
                    // 售价-成本=单间商品售价,考虑到不同的商品可能是不同的供应商
                    BigDecimal incomeNum = sumProfit.multiply(mallIncome.getIncomeProportion()).setScale(2, BigDecimal.ROUND_DOWN);
                    MallOrderIncome mallOrderIncome = new MallOrderIncome();
                    mallOrderIncome.setOrderId(mallOrder.getId());
                    mallOrderIncome.setIncomeUserId(byId.getUserId());
                    mallOrderIncome.setIncomeNum(incomeNum);
                    mallOrderIncome.setCancelIncomePrice(BigDecimal.ZERO);
                    mallOrderIncome.setRealIncomePrice(incomeNum);
                    mallOrderIncome.setIncomeType(IncomeTypeEnum.SUPPLY_CHAIN);
                    mallOrderIncome.setIncomeName(mallIncome.getIncomeName());
                    mallOrderIncome.setIncomeProportion(mallIncome.getIncomeProportion());
                    mallOrderIncome.setIncomeStatus(MallOrderIncomeTypeEnum.WAITING_ACCOUNT);
                    mallOrderIncome.setIsTeamIncome(Boolean.FALSE);
                    mallOrderIncome.setIncomeHierarchy(IncomeHierarchyEnum.SUPPLY_CHAIN);
                    mallOrderIncome.setIncomeHierarchyName(IncomeHierarchyEnum.SUPPLY_CHAIN.getDescription());
                    mallOrderIncome.setIncomeCardinality(sumProfit);
                    mallOrderIncome.setIsEfficient(Boolean.FALSE);
                    mallOrderIncome.setRemark(StrUtil.format("供应商推荐收益-{}", byId.getSupplierName()));
                    mallOrderIncome.insert();
                }

            }
        }


        //  获取这个用户这一笔订单,收货地址.通过收货地址 匹配对应的藏品,通过藏品.找哪个人在持有他.持有他的人.给他分润.


        // 通过省市区,获取绑定的哪个藏品.通过藏品获取谁在持有.有就开始分润 没有就不给,1个区可能会绑定多个藏品.如果有多个的情况下需要均分.
        List<NftRegionBinding> nftRegionBindings = nftRegionBindingDao.selectProvinceAndCityAndAreaAndEffectiveTime(mallOrder.getProvince(), mallOrder.getCity(), mallOrder.getArea());
        if (CollUtil.isNotEmpty(nftRegionBindings)) {
            // 不为空的情况下,获取所有拥有这个藏品id的用户
            List<Long> collectionId = nftRegionBindings.stream().map(NftRegionBinding::getCollectionId).collect(Collectors.toList());
            List<UserCollection> userCollections = userCollectionDao.selectByCollectionIds(collectionId);
            //  挂单了,但是没卖掉,权益就存在. 2023-10-13 下午五点左右和邓思行确认
            if (CollUtil.isNotEmpty(userCollections)) {
                // 有权益的用户,算一下权益分配.这个地区有多少个权益,获取多少的权益分配.
                List<MallIncome> directPurchaseList = list.stream()
                        .filter(mallIncome -> mallIncome.getIncomeType() == IncomeTypeEnum.COPYRIGHT_INCOME)
                        .sorted(Comparator.comparing(MallIncome::getIncomeProportion).reversed())
                        .collect(Collectors.toList());
                directPurchaseList.forEach(mallIncome -> {
                    // 计算有收益的用户,每个人应该分多少百分比.
                    BigDecimal divide = mallIncome.getIncomeProportion().divide(Convert.toBigDecimal(userCollections.size()), 2, BigDecimal.ROUND_DOWN);
                    // 每个人占据的百分比进行分钱.
                    userCollections.forEach(userCollection -> {
                        // 幂等性效验
//                        MallOrderIncome incomeUserIdAndIncomeTypeAndOrderId = getOneByIncomeUserIdAndIncomeTypeAndOrderId(userCollection.getUserId(), IncomeTypeEnum.COPYRIGHT_INCOME, mallOrder.getId());
//                        if(ObjectUtil.isNotNull(incomeUserIdAndIncomeTypeAndOrderId)){
//                            return;
//                        }
                        BigDecimal incomeNum = sumProfit.multiply(divide).setScale(2, BigDecimal.ROUND_DOWN);
                        MallOrderIncome mallOrderIncome = new MallOrderIncome();
                        mallOrderIncome.setOrderId(mallOrder.getId());
                        mallOrderIncome.setIncomeUserId(userCollection.getUserId());
                        mallOrderIncome.setIncomeNum(incomeNum);
                        mallOrderIncome.setCancelIncomePrice(BigDecimal.ZERO);
                        mallOrderIncome.setRealIncomePrice(incomeNum);
                        mallOrderIncome.setIncomeType(IncomeTypeEnum.COPYRIGHT_INCOME);
                        mallOrderIncome.setIncomeName(mallIncome.getIncomeName());
                        mallOrderIncome.setIncomeProportion(mallIncome.getIncomeProportion());
                        mallOrderIncome.setIncomeStatus(MallOrderIncomeTypeEnum.WAITING_ACCOUNT);
                        mallOrderIncome.setIsTeamIncome(Boolean.FALSE);
                        mallOrderIncome.setIncomeHierarchy(IncomeHierarchyEnum.COPYRIGHT);
                        mallOrderIncome.setIncomeHierarchyName(IncomeHierarchyEnum.COPYRIGHT.getDescription());
                        mallOrderIncome.setIncomeCardinality(sumProfit);
                        mallOrderIncome.setCollectionId(userCollection.getCollectionId());
                        mallOrderIncome.setIsEfficient(Boolean.FALSE);
                        mallOrderIncome.setRemark(StrUtil.format("版权收益-{}", userCollection.getFirstTitle()));
                        mallOrderIncome.insert();
                    });
                });
            }
        }


        if (list.size() == 0) {
            return;
        }

        if (ObjectUtil.isNull(user.getRecommendUserId()) || user.getRecommendUserId().intValue() == 0) {
            return;
        }

        //直推人
        UserInfo recommendUser = userInfoDao.getById(user.getRecommendUserId());
        if (ObjectUtil.isNull(recommendUser)) {
            return;
        }
        //过滤直推收益的集合
        List<MallIncome> directPurchaseList = list.stream()
                .filter(mallIncome -> mallIncome.getIncomeType() == IncomeTypeEnum.IP_MALL_DIRECT_PURCHASE)
                .sorted(Comparator.comparing(MallIncome::getIncomeProportion).reversed())
                .collect(Collectors.toList());


        Long pushStraightIncomeUserId = 0L;
        Long pushBetweenIncomeUserId = 0L;
        Long cityServerIncomeUserId = 0L;
        //直推收益
        for (MallIncome mallIncome : directPurchaseList) {
            int count = userCollectionService.getIsContainsAndIsHoldAndIsOpenAndOnConsignByCollectionId(mallIncome.getCollectionId(), recommendUser.getId());
            if (count > 0) {
                //幂等性校验
                MallOrderIncome incomeUserIdAndIncomeTypeAndOrderId = getOneByIncomeUserIdAndIncomeTypeAndOrderId(recommendUser.getId(), IncomeTypeEnum.IP_MALL_DIRECT_PURCHASE, mallOrder.getId());
                if (ObjectUtil.isNotNull(incomeUserIdAndIncomeTypeAndOrderId)) {
                    break;
                }
                pushStraightIncomeUserId = ObjectUtil.isNull(recommendUser.getId()) ? 0L : recommendUser.getId();
                //计算收益金额
                BigDecimal incomeNum = sumProfit.multiply(mallIncome.getIncomeProportion()).setScale(2, BigDecimal.ROUND_DOWN);
                MallOrderIncome mallOrderIncome = new MallOrderIncome();
                mallOrderIncome.setOrderId(mallOrder.getId());
                mallOrderIncome.setIncomeUserId(recommendUser.getId());
                mallOrderIncome.setIncomeNum(incomeNum);
                mallOrderIncome.setCancelIncomePrice(BigDecimal.ZERO);
                mallOrderIncome.setRealIncomePrice(incomeNum);
                mallOrderIncome.setIncomeType(IncomeTypeEnum.IP_MALL_DIRECT_PURCHASE);
                mallOrderIncome.setIncomeName(mallIncome.getIncomeName());
                mallOrderIncome.setIncomeProportion(mallIncome.getIncomeProportion());
                mallOrderIncome.setIncomeStatus(MallOrderIncomeTypeEnum.WAITING_ACCOUNT);
                mallOrderIncome.setIsTeamIncome(Boolean.FALSE);
                mallOrderIncome.setIncomeHierarchy(IncomeHierarchyEnum.PUSH_STRAIGHT);
                mallOrderIncome.setIncomeHierarchyName(IncomeHierarchyEnum.PUSH_STRAIGHT.getDescription());
                mallOrderIncome.setIncomeCardinality(sumProfit);
                mallOrderIncome.setIsEfficient(Boolean.FALSE);
                mallOrderIncome.insert();
                break;
            }
        }

        //间推收益
        if (ObjectUtil.isNotNull(recommendUser.getRecommendUserId()) || recommendUser.getRecommendUserId().intValue() != 0) {
            List<MallIncome> interimPurchaseList = list.stream()
                    .filter(mallIncome -> mallIncome.getIncomeType() == IncomeTypeEnum.IP_MALL_INTERIM_PURCHASE)
                    .sorted(Comparator.comparing(MallIncome::getIncomeProportion).reversed())
                    .collect(Collectors.toList());

            for (MallIncome mallIncome : interimPurchaseList) {
                int count = userCollectionService.getIsContainsAndIsHoldAndIsOpenAndOnConsignByCollectionId(mallIncome.getCollectionId(), recommendUser.getRecommendUserId());
                if (count > 0) {
                    //幂等性校验
                    MallOrderIncome incomeUserIdAndIncomeTypeAndOrderId = getOneByIncomeUserIdAndIncomeTypeAndOrderId(recommendUser.getRecommendUserId(), IncomeTypeEnum.IP_MALL_INTERIM_PURCHASE, mallOrder.getId());
                    if (ObjectUtil.isNotNull(incomeUserIdAndIncomeTypeAndOrderId)) {
                        break;
                    }
                    pushBetweenIncomeUserId = ObjectUtil.isNull(recommendUser.getRecommendUserId()) ? 0L : recommendUser.getRecommendUserId();
                    //计算收益金额
                    BigDecimal incomeNum = sumProfit.multiply(mallIncome.getIncomeProportion()).setScale(2, BigDecimal.ROUND_DOWN);
                    MallOrderIncome mallOrderIncome = new MallOrderIncome();
                    mallOrderIncome.setOrderId(mallOrder.getId());
                    mallOrderIncome.setIncomeUserId(recommendUser.getRecommendUserId());
                    mallOrderIncome.setIncomeNum(incomeNum);
                    mallOrderIncome.setCancelIncomePrice(BigDecimal.ZERO);
                    mallOrderIncome.setRealIncomePrice(incomeNum);
                    mallOrderIncome.setIncomeType(IncomeTypeEnum.IP_MALL_INTERIM_PURCHASE);
                    mallOrderIncome.setIncomeName(mallIncome.getIncomeName());
                    mallOrderIncome.setIncomeProportion(mallIncome.getIncomeProportion());
                    mallOrderIncome.setIncomeStatus(MallOrderIncomeTypeEnum.WAITING_ACCOUNT);
                    mallOrderIncome.setIsTeamIncome(Boolean.FALSE);
                    mallOrderIncome.setIncomeHierarchy(IncomeHierarchyEnum.PUSH_BETWEEN);
                    mallOrderIncome.setIncomeHierarchyName(IncomeHierarchyEnum.PUSH_BETWEEN.getDescription());
                    mallOrderIncome.setIncomeCardinality(sumProfit);
                    mallOrderIncome.setIsEfficient(Boolean.FALSE);
                    mallOrderIncome.insert();
                    break;
                }
            }
        }


        //获取最近的城市服务中心
        Long cityServiceUserId = userCityServerCentreDao.accessTheNearestCityServiceCenter(user.getId());
        //城市服务中心收益
        if (ObjectUtil.isNotNull(cityServiceUserId) && cityServiceUserId.intValue() != 0) {
            List<MallIncome> cityServerCenterList = list.stream()
                    .filter(mallIncome -> mallIncome.getIncomeType() == IncomeTypeEnum.IP_MALL_CITY_SERVER_CENTER)
                    .sorted(Comparator.comparing(MallIncome::getIncomeProportion).reversed())
                    .collect(Collectors.toList());

            for (MallIncome mallIncome : cityServerCenterList) {
                //幂等性校验
                MallOrderIncome incomeUserIdAndIncomeTypeAndOrderId = getOneByIncomeUserIdAndIncomeTypeAndOrderId(cityServiceUserId, IncomeTypeEnum.IP_MALL_CITY_SERVER_CENTER, mallOrder.getId());
                if (ObjectUtil.isNotNull(incomeUserIdAndIncomeTypeAndOrderId)) {
                    break;
                }
                cityServerIncomeUserId = ObjectUtil.isNull(cityServiceUserId) ? 0L : cityServiceUserId;
                //计算收益金额
                BigDecimal incomeNum = sumProfit.multiply(mallIncome.getIncomeProportion()).setScale(2, BigDecimal.ROUND_DOWN);
                MallOrderIncome mallOrderIncome = new MallOrderIncome();
                mallOrderIncome.setOrderId(mallOrder.getId());
                mallOrderIncome.setIncomeUserId(cityServiceUserId);
                mallOrderIncome.setIncomeNum(incomeNum);
                mallOrderIncome.setCancelIncomePrice(BigDecimal.ZERO);
                mallOrderIncome.setRealIncomePrice(incomeNum);
                mallOrderIncome.setIncomeType(IncomeTypeEnum.IP_MALL_CITY_SERVER_CENTER);
                mallOrderIncome.setIncomeName(mallIncome.getIncomeName());
                mallOrderIncome.setIncomeProportion(mallIncome.getIncomeProportion());
                mallOrderIncome.setIncomeStatus(MallOrderIncomeTypeEnum.WAITING_ACCOUNT);
                mallOrderIncome.setIsTeamIncome(Boolean.FALSE);
                mallOrderIncome.setIncomeHierarchy(IncomeHierarchyEnum.SPECIAL);
                mallOrderIncome.setIncomeHierarchyName(IncomeHierarchyEnum.SPECIAL.getDescription());
                mallOrderIncome.setIncomeCardinality(sumProfit);
                mallOrderIncome.setIsEfficient(Boolean.FALSE);
                mallOrderIncome.insert();
                break;
            }

        }

        // 获取最近的社区网点
        Long communityNetworkUserId = userWorkRoomDao.accessTheNearestCityServiceCenter(user.getId());

        if (ObjectUtil.isNotNull(communityNetworkUserId) && communityNetworkUserId.intValue() != 0) {
            List<MallIncome> cityServerCenterList = list.stream()
                    .filter(mallIncome -> mallIncome.getIncomeType() == IncomeTypeEnum.IP_MALL_NETWORK_REVENUE)
                    .sorted(Comparator.comparing(MallIncome::getIncomeProportion).reversed())
                    .collect(Collectors.toList());

            for (MallIncome mallIncome : cityServerCenterList) {
                //幂等性校验
                MallOrderIncome incomeUserIdAndIncomeTypeAndOrderId = getOneByIncomeUserIdAndIncomeTypeAndOrderId(communityNetworkUserId, IncomeTypeEnum.IP_MALL_NETWORK_REVENUE, mallOrder.getId());
                if (ObjectUtil.isNotNull(incomeUserIdAndIncomeTypeAndOrderId)) {
                    break;
                }
                cityServerIncomeUserId = ObjectUtil.isNull(communityNetworkUserId) ? 0L : communityNetworkUserId;
                //计算收益金额
                BigDecimal incomeNum = sumProfit.multiply(mallIncome.getIncomeProportion()).setScale(2, BigDecimal.ROUND_DOWN);
                MallOrderIncome mallOrderIncome = new MallOrderIncome();
                mallOrderIncome.setOrderId(mallOrder.getId());
                mallOrderIncome.setIncomeUserId(communityNetworkUserId);
                mallOrderIncome.setIncomeNum(incomeNum);
                mallOrderIncome.setCancelIncomePrice(BigDecimal.ZERO);
                mallOrderIncome.setRealIncomePrice(incomeNum);
                mallOrderIncome.setIncomeType(IncomeTypeEnum.IP_MALL_NETWORK_REVENUE);
                mallOrderIncome.setIncomeName(mallIncome.getIncomeName());
                mallOrderIncome.setIncomeProportion(mallIncome.getIncomeProportion());
                mallOrderIncome.setIncomeStatus(MallOrderIncomeTypeEnum.WAITING_ACCOUNT);
                mallOrderIncome.setIsTeamIncome(Boolean.FALSE);
                mallOrderIncome.setIncomeHierarchy(IncomeHierarchyEnum.SPECIAL);
                mallOrderIncome.setIncomeHierarchyName(IncomeHierarchyEnum.SPECIAL.getDescription());
                mallOrderIncome.setIncomeCardinality(sumProfit);
                mallOrderIncome.setIsEfficient(Boolean.FALSE);
                mallOrderIncome.insert();
                break;
            }

        }
        Assert.isTrue(mallOrderService.updateIncomeUserId(mallOrder.getId(), pushStraightIncomeUserId, pushBetweenIncomeUserId, cityServerIncomeUserId), () -> new GlobalRunTimeException(ErrorCode.THE_SYSTEM_IS_BUSY_PLEASE_TRY_AGAIN_LATER));
    }

    /**
     * 新计算收益
     *
     * @param orderProdcutList
     * @param mallOrder
     * @param user
     */
    @Override
    public void newCalCulateIncome(List<MallOrderProduct> orderProdcutList, MallOrder mallOrder, UserInfo user) {
        // 幂等性效验
        List<MallOrderIncome> mallOrderIncomeList = getListByOrderId(mallOrder.getId());
        if (!CollectionUtils.isEmpty(mallOrderIncomeList)) {
            return;
        }
        //总售价
        BigDecimal sumProductSalesPrice = BigDecimal.ZERO;
        //总成本价
        BigDecimal sumproductCostPrice = BigDecimal.ZERO;

        BigDecimal couponAmount = BigDecimal.ZERO;
        if (Objects.nonNull(mallOrder.getCouponAmount())) {
            couponAmount = mallOrder.getCouponAmount();
        }
        for (MallOrderProduct mallOrderProduct : orderProdcutList) {
            BigDecimal singleSalesPrice = mallOrderProduct.getProductSalesPrice().multiply(Convert.toBigDecimal(mallOrderProduct.getProductNum()));
            sumProductSalesPrice = sumProductSalesPrice.add(singleSalesPrice);
            // 总成本
            BigDecimal singleCostPrice = BigDecimalUtils.add(mallOrderProduct.getProductCostPrice(), mallOrderProduct.getActivityCostPrice(), mallOrderProduct.getReservePrice()).multiply(Convert.toBigDecimal(mallOrderProduct.getProductNum()));
            sumproductCostPrice = sumproductCostPrice.add(singleCostPrice);
        }
        //总利润 计算收益金额
        BigDecimal sumProfit = sumProductSalesPrice.subtract(sumproductCostPrice).subtract(couponAmount);
        // 已分配利润
        BigDecimal distributedProfits = BigDecimal.ZERO;
        if (BigDecimalUtils.compareTo(BigDecimal.ZERO, sumProfit)) {
            // 利润小于等于0 不分
            return;
        }
        // 获取分润模版
        MallOrderProduct mallOrderProduct = orderProdcutList.get(0);
        MallActivitySpecs mallActivitySpecs = mallActivitySpecsService.getById(mallOrderProduct.getActivitySpecsId());
        if (Objects.isNull(mallActivitySpecs.getProfitTemplateId())) {
            return;
        }
        // 分润模版
        MallProfitTemplate mallProfitTemplate = mallProfitTemplateService.getById(mallActivitySpecs.getProfitTemplateId());
        if (Objects.isNull(mallProfitTemplate)) {
            return;
        }
        // 直推收益
        if (BigDecimalUtils.greaterZero(mallProfitTemplate.getDirectIncome())) {
            // 有直推收益
            distributedProfits = buildDirectIncome(user, mallOrder, mallProfitTemplate, sumProfit, distributedProfits);
        }
        // 供应商推荐人收益
        if (BigDecimalUtils.greaterZero(mallProfitTemplate.getSupplierReferrerIncome())) {
            // 有供应商推荐人收益
            distributedProfits = buildSupplierReferrerIncome(mallOrder, mallProfitTemplate, sumProfit, distributedProfits, mallOrderProduct);
        }
        // 地图收益
        if (BigDecimalUtils.greaterZero(mallProfitTemplate.getMapIncome())) {
            // 有地图收益
            distributedProfits = buildMapIncome(mallOrder, mallProfitTemplate, sumProfit, distributedProfits, mallOrderProduct.getProductName());
        }
        // 城市服务中心收益
        if (BigDecimalUtils.greaterZero(mallProfitTemplate.getUrbanServiceCenterIncome())) {
            // 有城市服务中心收益
            distributedProfits = buildUrbanServiceCenterIncome(user, mallOrder, mallProfitTemplate, sumProfit, distributedProfits);
        }
        // 社区工作室收益
        if (BigDecimalUtils.greaterZero(mallProfitTemplate.getCommunityStudioIncome())) {
            // 有社区工作室收益
            distributedProfits = buildCommunityStudioIncome(user, mallOrder, mallProfitTemplate, sumProfit, distributedProfits);
        }
        // 玛特收益
        if (BigDecimalUtils.greaterZero(mallProfitTemplate.getMetaIncome())) {
            // 有玛特收益
            distributedProfits = buildMetaIncome(mallOrder, mallProfitTemplate, sumProfit, distributedProfits);
        }
        // 生态商品收益
        if (BigDecimalUtils.greaterZero(mallProfitTemplate.getEcologicalCommodityIncome())) {
            // 有生态商品收益
            distributedProfits = buildEcologicalCommodityIncome(user, mallOrder, mallProfitTemplate, sumProfit, distributedProfits);
        }
        // 有NONO商城收益
        buildMallIncome(mallOrder, mallProfitTemplate, sumProfit, distributedProfits);
    }

    /**
     * 小程序订单新计算收益
     *
     * @param orderProdcutList
     * @param mallOrder
     * @param wxMiniUserInfo
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ProfitTemplateGetProfitAndPointsVO wxMiniNewCalCulateIncome(List<MallOrderProduct> orderProdcutList, MallOrder mallOrder, WxMiniUserInfo wxMiniUserInfo) {
        // 幂等性效验
        List<MallOrderIncome> mallOrderIncomeList = getListByOrderId(mallOrder.getId());
        if (!CollectionUtils.isEmpty(mallOrderIncomeList)) {
            return new ProfitTemplateGetProfitAndPointsVO();
        }
        //总售价
        BigDecimal sumProductSalesPrice = BigDecimal.ZERO;
        //总成本价
        BigDecimal sumproductCostPrice = BigDecimal.ZERO;

        BigDecimal couponAmount = BigDecimal.ZERO;
        if (Objects.nonNull(mallOrder.getCouponAmount())) {
            couponAmount = mallOrder.getCouponAmount();
        }
        for (MallOrderProduct mallOrderProduct : orderProdcutList) {
            BigDecimal singleSalesPrice = mallOrderProduct.getProductSalesPrice().multiply(Convert.toBigDecimal(mallOrderProduct.getProductNum()));
            sumProductSalesPrice = sumProductSalesPrice.add(singleSalesPrice);
            // 总成本
            BigDecimal singleCostPrice = BigDecimalUtils.add(mallOrderProduct.getProductCostPrice(), mallOrderProduct.getActivityCostPrice(), mallOrderProduct.getReservePrice()).multiply(Convert.toBigDecimal(mallOrderProduct.getProductNum()));
            sumproductCostPrice = sumproductCostPrice.add(singleCostPrice);
        }
        //总利润 计算收益金额
        BigDecimal sumProfit = sumProductSalesPrice.subtract(sumproductCostPrice).subtract(couponAmount);

        return wxMiniProfitTemplateClient.getProfitAndPoints(ProfitTemplateGetProfitAndPointsReq.build(orderProdcutList.get(0).getActivityId(), sumProfit, mallOrder.getPayPrice()));

    }

    /**
     * 直推收益封装
     *
     * @param user
     * @param mallOrder
     * @param mallProfitTemplate
     * @param sumProfit
     * @param distributedProfits
     */
    private BigDecimal buildDirectIncome(UserInfo user, MallOrder mallOrder, MallProfitTemplate mallProfitTemplate, BigDecimal sumProfit, BigDecimal distributedProfits) {
        //直推人
        UserInfo recommendUser = userInfoDao.getById(user.getRecommendUserId());
        if (Objects.isNull(recommendUser)) {
            return distributedProfits;
        }
        String collectionIdStr = mallProfitTemplate.getCollectionId();
        List<Long> collectionIds = JSONArray.parseArray(collectionIdStr, Long.class);
        int count = userCollectionService.getIsContainsAndIsHoldAndIsOpenAndOnConsignByCollectionIds(collectionIds, recommendUser.getId());
        if (count > 0) {
            BigDecimal directIncome = sumProfit.multiply(mallProfitTemplate.getDirectIncome()).setScale(2, BigDecimal.ROUND_DOWN);
            distributedProfits = distributedProfits.add(directIncome);
            MallOrderIncome mallOrderIncome = new MallOrderIncome();
            mallOrderIncome.setOrderId(mallOrder.getId());
            mallOrderIncome.setIncomeUserId(recommendUser.getId());
            mallOrderIncome.setIncomeNum(directIncome);
            mallOrderIncome.setCancelIncomePrice(BigDecimal.ZERO);
            mallOrderIncome.setRealIncomePrice(directIncome);
            mallOrderIncome.setIncomeType(IncomeTypeEnum.IP_MALL_DIRECT_PURCHASE);
            mallOrderIncome.setIncomeName(IncomeTypeEnum.IP_MALL_DIRECT_PURCHASE.getDescription());
            mallOrderIncome.setIncomeProportion(mallProfitTemplate.getDirectIncome());
            mallOrderIncome.setIncomeStatus(MallOrderIncomeTypeEnum.WAITING_ACCOUNT);
            mallOrderIncome.setIsTeamIncome(Boolean.FALSE);
            mallOrderIncome.setIncomeHierarchy(IncomeHierarchyEnum.PUSH_STRAIGHT);
            mallOrderIncome.setIncomeHierarchyName(IncomeHierarchyEnum.PUSH_STRAIGHT.getDescription());
            mallOrderIncome.setIncomeCardinality(sumProfit);
            mallOrderIncome.setIsEfficient(Boolean.FALSE);
            mallOrderIncome.setRemark(StrUtil.format("直推收益-{}", recommendUser.getUserTel()));
            mallOrderIncome.insert();
        }
        return distributedProfits;
    }


    /**
     * 供应商推荐人收益
     *
     * @param mallOrder
     * @param mallProfitTemplate
     * @param sumProfit
     * @param distributedProfits
     */
    private BigDecimal buildSupplierReferrerIncome(MallOrder mallOrder, MallProfitTemplate mallProfitTemplate, BigDecimal sumProfit, BigDecimal distributedProfits, MallOrderProduct mallOrderProduct) {
        // 根据产品的id获取供应商对应的推荐人.对他进行分钱.
        SupplierManageBinding supplierManageBinding = supplierManageBindingDao.getMallId(mallOrderProduct.getProductId());
        if (Objects.isNull(supplierManageBinding)) {
            return distributedProfits;
        }
        SupplierManagePageVO supplierManagePageVO = supplierManageDao.getById(supplierManageBinding.getSupplierId());
        if (Objects.isNull(supplierManagePageVO) || Objects.isNull(supplierManagePageVO.getUserId())) {
            return distributedProfits;
        }
        BigDecimal supplierReferrerIncome = sumProfit.multiply(mallProfitTemplate.getSupplierReferrerIncome()).setScale(2, BigDecimal.ROUND_DOWN);
        distributedProfits = distributedProfits.add(supplierReferrerIncome);
        MallOrderIncome mallOrderIncome = new MallOrderIncome();
        mallOrderIncome.setOrderId(mallOrder.getId());
        mallOrderIncome.setIncomeUserId(supplierManagePageVO.getUserId());
        mallOrderIncome.setIncomeNum(supplierReferrerIncome);
        mallOrderIncome.setCancelIncomePrice(BigDecimal.ZERO);
        mallOrderIncome.setRealIncomePrice(supplierReferrerIncome);
        mallOrderIncome.setIncomeType(IncomeTypeEnum.SUPPLY_CHAIN);
        mallOrderIncome.setIncomeName(IncomeTypeEnum.SUPPLY_CHAIN.getDescription());
        mallOrderIncome.setIncomeProportion(mallProfitTemplate.getSupplierReferrerIncome());
        mallOrderIncome.setIncomeStatus(MallOrderIncomeTypeEnum.WAITING_ACCOUNT);
        mallOrderIncome.setIsTeamIncome(Boolean.FALSE);
        mallOrderIncome.setIncomeHierarchy(IncomeHierarchyEnum.SUPPLY_CHAIN);
        mallOrderIncome.setIncomeHierarchyName(IncomeHierarchyEnum.SUPPLY_CHAIN.getDescription());
        mallOrderIncome.setIncomeCardinality(sumProfit);
        mallOrderIncome.setIsEfficient(Boolean.FALSE);
        mallOrderIncome.setRemark(StrUtil.format("供应商推荐收益-{}", supplierManagePageVO.getSupplierName()));
        mallOrderIncome.insert();
        return distributedProfits;
    }


    /**
     * 地图收益
     *
     * @param mallOrder
     * @param mallProfitTemplate
     * @param sumProfit
     * @param distributedProfits
     */
    private BigDecimal buildMapIncome(MallOrder mallOrder, MallProfitTemplate mallProfitTemplate, BigDecimal sumProfit, BigDecimal distributedProfits, String productName) {
        if (Objects.isNull(mallProfitTemplate.getMapIncome()) || mallProfitTemplate.getMapIncome().compareTo(BigDecimal.ZERO) <= 0) {
            return BigDecimal.ZERO;
        }
        if (NumberUtil.isGreater(mallOrder.getWishBalancePrice(), BigDecimal.ZERO)) {
            return BigDecimal.ZERO;
        }
        if (mallOrder.getIsVirtual()) {
            return BigDecimal.ZERO;
        }
        if (mallOrder.getActivityType() == ActivityTypeEnum.EXCHANGE) {
            return BigDecimal.ZERO;
        }
        // 通过省市区,获取绑定的哪个藏品.通过藏品获取谁在持有.有就开始分润 没有就不给,1个区可能会绑定多个藏品.如果有多个的情况下需要均分.
        List<NftRegionBinding> nftRegionBindings = nftRegionBindingDao.selectProvinceAndCityAndAreaAndEffectiveTime(mallOrder.getProvince(), mallOrder.getCity(), mallOrder.getArea());
        if (CollectionUtils.isEmpty(nftRegionBindings)) {
            return distributedProfits;
        }
        NftRegionBinding nftRegionBinding = nftRegionBindings.get(0);
        if (Objects.isNull(nftRegionBinding.getEffectiveTime())) {
            return distributedProfits;
        }
        LocalDateTime date = LocalDateTimeUtil.dateToLocalDateTime(nftRegionBinding.getEffectiveTime());
        if (date.isBefore(LocalDateTime.now())) {
            return distributedProfits;
        }
        // 不为空的情况下,获取所有拥有这个藏品id的用户
        List<Long> collectionId = nftRegionBindings.stream().map(NftRegionBinding::getCollectionId).collect(Collectors.toList());
        List<UserCollection> userCollections = userCollectionDao.selectByCollectionIds(collectionId);
        //  挂单了,但是没卖掉,权益就存在. 2023-10-13 下午五点左右和邓思行确认
        if (CollUtil.isNotEmpty(userCollections)) {
            // 平均分给每一个收益的人
            for (UserCollection userCollection : userCollections) {
                BigDecimal userCollectionDivide = mallProfitTemplate.getMapIncome().divide(Convert.toBigDecimal(userCollections.size()), 4, BigDecimal.ROUND_DOWN);
                // 分给每一个人的地图收益
                BigDecimal userMapIncome = sumProfit.multiply(userCollectionDivide).setScale(2, BigDecimal.ROUND_DOWN);
                distributedProfits = distributedProfits.add(userMapIncome);
                MallOrderIncome mallOrderIncome = new MallOrderIncome();
                mallOrderIncome.setOrderId(mallOrder.getId());
                mallOrderIncome.setIncomeUserId(userCollection.getUserId());
                mallOrderIncome.setIncomeNum(userMapIncome);
                mallOrderIncome.setCancelIncomePrice(BigDecimal.ZERO);
                mallOrderIncome.setRealIncomePrice(userMapIncome);
                mallOrderIncome.setIncomeType(IncomeTypeEnum.COPYRIGHT_INCOME);
                mallOrderIncome.setIncomeName(IncomeTypeEnum.COPYRIGHT_INCOME.getDescription());
                mallOrderIncome.setIncomeProportion(userCollectionDivide);
                mallOrderIncome.setIncomeStatus(MallOrderIncomeTypeEnum.WAITING_ACCOUNT);
                mallOrderIncome.setIsTeamIncome(Boolean.FALSE);
                mallOrderIncome.setIncomeHierarchy(IncomeHierarchyEnum.COPYRIGHT);
                mallOrderIncome.setIncomeHierarchyName(IncomeHierarchyEnum.COPYRIGHT.getDescription());
                mallOrderIncome.setIncomeCardinality(sumProfit);
                mallOrderIncome.setCollectionId(userCollection.getCollectionId());
                mallOrderIncome.setIsEfficient(Boolean.FALSE);
                mallOrderIncome.setRemark(StrUtil.format("版权收益-{}", userCollection.getFirstTitle()));
                mallOrderIncome.insert();
                TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
                    @Override
                    public void afterCommit() {
                        MetaMapSettleDTO metaMapSettleDTO = new MetaMapSettleDTO();
                        metaMapSettleDTO.setWishBalancePrice(new BigDecimal(0));
                        MetaMapSettleDTO mall = metaMapSettleDTO.mall(mallOrder.getOrderNo(), productName, mallOrder.getUserId(), MetaMapSettleSourceTypeEnum.MALL, mallOrderIncome.getRealIncomePrice(), BigDecimal.ZERO, mallProfitTemplate.getId(), nftRegionBindings.get(0).getProvinceName(), nftRegionBindings.get(0).getCityName(), nftRegionBindings.get(0).getRegionName());
                        messageQueueHelper.sendMessage(MessageTopic.META_MAP_SETTLE, mall, MessageTopic.META_MAP_SETTLE, mallOrder.getOrderNo());
                    }
                });
            }
        }
        return distributedProfits;
    }

    /**
     * 城市中心收益
     *
     * @param mallOrder
     * @param mallProfitTemplate
     * @param sumProfit
     * @param distributedProfits
     */
    private BigDecimal buildUrbanServiceCenterIncome(UserInfo user, MallOrder mallOrder, MallProfitTemplate mallProfitTemplate, BigDecimal sumProfit, BigDecimal distributedProfits) {
        //获取最近的城市服务中心
        Long cityServiceUserId = userCityServerCentreDao.accessTheNearestCityServiceCenter(user.getId());
        if (Objects.isNull(cityServiceUserId)) {
            return distributedProfits;
        }
        // 计算金额
        BigDecimal urbanServiceCenterIncome = sumProfit.multiply(mallProfitTemplate.getUrbanServiceCenterIncome()).setScale(2, BigDecimal.ROUND_DOWN);
        distributedProfits = distributedProfits.add(urbanServiceCenterIncome);
        MallOrderIncome mallOrderIncome = new MallOrderIncome();
        mallOrderIncome.setOrderId(mallOrder.getId());
        mallOrderIncome.setIncomeUserId(cityServiceUserId);
        mallOrderIncome.setIncomeNum(urbanServiceCenterIncome);
        mallOrderIncome.setCancelIncomePrice(BigDecimal.ZERO);
        mallOrderIncome.setRealIncomePrice(urbanServiceCenterIncome);
        mallOrderIncome.setIncomeType(IncomeTypeEnum.IP_MALL_CITY_SERVER_CENTER);
        mallOrderIncome.setIncomeName(IncomeTypeEnum.IP_MALL_CITY_SERVER_CENTER.getDescription());
        mallOrderIncome.setIncomeProportion(mallProfitTemplate.getUrbanServiceCenterIncome());
        mallOrderIncome.setIncomeStatus(MallOrderIncomeTypeEnum.WAITING_ACCOUNT);
        mallOrderIncome.setIsTeamIncome(Boolean.FALSE);
        mallOrderIncome.setIncomeHierarchy(IncomeHierarchyEnum.SPECIAL);
        mallOrderIncome.setIncomeHierarchyName(IncomeHierarchyEnum.SPECIAL.getDescription());
        mallOrderIncome.setIncomeCardinality(sumProfit);
        mallOrderIncome.setIsEfficient(Boolean.FALSE);
        mallOrderIncome.setRemark(StrUtil.format("城市中心收益-{}", cityServiceUserId));
        mallOrderIncome.insert();
        return distributedProfits;
    }

    /**
     * 社区网点收益
     *
     * @param mallOrder
     * @param mallProfitTemplate
     * @param sumProfit
     * @param distributedProfits
     */
    private BigDecimal buildCommunityStudioIncome(UserInfo user, MallOrder mallOrder, MallProfitTemplate mallProfitTemplate, BigDecimal sumProfit, BigDecimal distributedProfits) {
        //获取最近的城市服务中心
        Long communityNetworkUserId = userWorkRoomDao.accessTheNearestCityServiceCenter(user.getId());
        if (Objects.isNull(communityNetworkUserId)) {
            return distributedProfits;
        }
        // 计算金额
        BigDecimal communityStudioIncome = sumProfit.multiply(mallProfitTemplate.getCommunityStudioIncome()).setScale(2, BigDecimal.ROUND_DOWN);
        distributedProfits = distributedProfits.add(communityStudioIncome);
        MallOrderIncome mallOrderIncome = new MallOrderIncome();
        mallOrderIncome.setOrderId(mallOrder.getId());
        mallOrderIncome.setIncomeUserId(communityNetworkUserId);
        mallOrderIncome.setIncomeNum(communityStudioIncome);
        mallOrderIncome.setCancelIncomePrice(BigDecimal.ZERO);
        mallOrderIncome.setRealIncomePrice(communityStudioIncome);
        mallOrderIncome.setIncomeType(IncomeTypeEnum.IP_MALL_NETWORK_REVENUE);
        mallOrderIncome.setIncomeName(IncomeTypeEnum.IP_MALL_NETWORK_REVENUE.getDescription());
        mallOrderIncome.setIncomeProportion(mallProfitTemplate.getUrbanServiceCenterIncome());
        mallOrderIncome.setIncomeStatus(MallOrderIncomeTypeEnum.WAITING_ACCOUNT);
        mallOrderIncome.setIsTeamIncome(Boolean.FALSE);
        mallOrderIncome.setIncomeHierarchy(IncomeHierarchyEnum.SPECIAL);
        mallOrderIncome.setIncomeHierarchyName(IncomeHierarchyEnum.SPECIAL.getDescription());
        mallOrderIncome.setIncomeCardinality(sumProfit);
        mallOrderIncome.setIsEfficient(Boolean.FALSE);
        mallOrderIncome.setRemark(StrUtil.format("社区网点收益-{}", communityNetworkUserId));
        mallOrderIncome.insert();
        return distributedProfits;
    }

    /**
     * 玛特收益
     *
     * @param mallOrder
     * @param mallProfitTemplate
     * @param sumProfit
     * @param distributedProfits
     */
    private BigDecimal buildMetaIncome(MallOrder mallOrder, MallProfitTemplate mallProfitTemplate, BigDecimal sumProfit, BigDecimal distributedProfits) {

        // 计算金额
        BigDecimal metaIncome = sumProfit.multiply(mallProfitTemplate.getMetaIncome()).setScale(2, BigDecimal.ROUND_DOWN);
        // // 叠加已经分出去的收益
        distributedProfits = distributedProfits.add(metaIncome);
        // 瓜分分润
        BigDecimal carveUpIncome = metaIncome.multiply(mallProfitTemplate.getCarveUpRatio()).setScale(2, BigDecimal.ROUND_DOWN);
        // 排行榜分润
        BigDecimal rankingListIncome = metaIncome.multiply(mallProfitTemplate.getRankingListRatio()).setScale(2, BigDecimal.ROUND_DOWN);
        // 玛特收益
        metaIncome = metaIncome.subtract(carveUpIncome).subtract(rankingListIncome);

        MallOrderIncome mallOrderIncome = new MallOrderIncome();
        mallOrderIncome.setOrderId(mallOrder.getId());
        mallOrderIncome.setIncomeUserId(mallProfitTemplate.getMetaIncomeDaoId());
        mallOrderIncome.setIncomeNum(carveUpIncome);
        mallOrderIncome.setCancelIncomePrice(BigDecimal.ZERO);
        mallOrderIncome.setRealIncomePrice(carveUpIncome);
        mallOrderIncome.setIncomeType(IncomeTypeEnum.META_INCOME_DIVIDE);
        mallOrderIncome.setIncomeName(IncomeTypeEnum.META_INCOME_DIVIDE.getDescription());
        mallOrderIncome.setIncomeProportion(mallProfitTemplate.getCarveUpRatio());
        mallOrderIncome.setIncomeStatus(MallOrderIncomeTypeEnum.WAITING_ACCOUNT);
        mallOrderIncome.setIsTeamIncome(Boolean.FALSE);
        mallOrderIncome.setIncomeHierarchy(IncomeHierarchyEnum.SPECIAL);
        mallOrderIncome.setIncomeHierarchyName(IncomeHierarchyEnum.SPECIAL.getDescription());
        mallOrderIncome.setIncomeCardinality(sumProfit);
        mallOrderIncome.setIsEfficient(Boolean.FALSE);
        mallOrderIncome.setRemark(StrUtil.format("瓜分分润收益-{}", carveUpIncome));
        mallOrderIncome.insert();
        // 排行榜分润
        MallOrderIncome rankingListMallOrderIncome = new MallOrderIncome();
        rankingListMallOrderIncome.setOrderId(mallOrder.getId());
        rankingListMallOrderIncome.setIncomeUserId(mallProfitTemplate.getMetaIncomeDaoId());
        rankingListMallOrderIncome.setIncomeNum(rankingListIncome);
        rankingListMallOrderIncome.setCancelIncomePrice(BigDecimal.ZERO);
        rankingListMallOrderIncome.setRealIncomePrice(rankingListIncome);
        rankingListMallOrderIncome.setIncomeType(IncomeTypeEnum.META_INCOME_RANKING_LIST);
        rankingListMallOrderIncome.setIncomeName(IncomeTypeEnum.META_INCOME_RANKING_LIST.getDescription());
        rankingListMallOrderIncome.setIncomeProportion(mallProfitTemplate.getRankingListRatio());
        rankingListMallOrderIncome.setIncomeStatus(MallOrderIncomeTypeEnum.WAITING_ACCOUNT);
        rankingListMallOrderIncome.setIsTeamIncome(Boolean.FALSE);
        rankingListMallOrderIncome.setIncomeHierarchy(IncomeHierarchyEnum.SPECIAL);
        rankingListMallOrderIncome.setIncomeHierarchyName(IncomeHierarchyEnum.SPECIAL.getDescription());
        rankingListMallOrderIncome.setIncomeCardinality(sumProfit);
        rankingListMallOrderIncome.setIsEfficient(Boolean.FALSE);
        rankingListMallOrderIncome.setRemark(StrUtil.format("排行榜分润收益-{}", rankingListIncome));
        rankingListMallOrderIncome.insert();
        // 玛特收益
        MallOrderIncome meta = new MallOrderIncome();
        meta.setOrderId(mallOrder.getId());
        meta.setIncomeUserId(mallProfitTemplate.getMetaIncomeDaoId());
        meta.setIncomeNum(metaIncome);
        meta.setCancelIncomePrice(BigDecimal.ZERO);
        meta.setRealIncomePrice(metaIncome);
        meta.setIncomeType(IncomeTypeEnum.META_INCOME);
        meta.setIncomeName(IncomeTypeEnum.META_INCOME.getDescription());
        meta.setIncomeProportion(mallProfitTemplate.getMetaIncome());
        meta.setIncomeStatus(MallOrderIncomeTypeEnum.WAITING_ACCOUNT);
        meta.setIsTeamIncome(Boolean.FALSE);
        meta.setIncomeHierarchy(IncomeHierarchyEnum.SPECIAL);
        meta.setIncomeHierarchyName(IncomeHierarchyEnum.SPECIAL.getDescription());
        meta.setIncomeCardinality(sumProfit);
        meta.setIsEfficient(Boolean.FALSE);
        meta.setRemark(StrUtil.format("玛特收益-{}", metaIncome));
        meta.insert();
        return distributedProfits;
    }

    /**
     * 生态商品收益
     *
     * @param mallOrder
     * @param mallProfitTemplate
     * @param sumProfit
     * @param distributedProfits
     */
    private BigDecimal buildEcologicalCommodityIncome(UserInfo user, MallOrder mallOrder, MallProfitTemplate mallProfitTemplate, BigDecimal sumProfit, BigDecimal distributedProfits) {

        // 计算金额
        BigDecimal ecologicalCommodityIncome = sumProfit.multiply(mallProfitTemplate.getEcologicalCommodityIncome()).setScale(2, BigDecimal.ROUND_DOWN);
        // 购买人网体所属DAO分润
        BigDecimal purchaserDaoRatioIncome = ecologicalCommodityIncome.multiply(mallProfitTemplate.getPurchaserDaoRatio()).setScale(2, BigDecimal.ROUND_DOWN);
        // 平台分润
        BigDecimal ecologicalCommodityIncomeDaoIncome = ecologicalCommodityIncome.subtract(purchaserDaoRatioIncome);
        // 叠加已经分出去的收益
        distributedProfits = distributedProfits.add(ecologicalCommodityIncomeDaoIncome);
        // 创建网体所属dao分润记录
        // 获取用户所属的网体
        Long daoId = userCreatorInfoService.theNetworkToWhichTheUserBelongs(user.getId());
        if (Objects.nonNull(daoId) && 0L != daoId) {
            MallOrderIncome mallOrderIncome = new MallOrderIncome();
            mallOrderIncome.setOrderId(mallOrder.getId());
            mallOrderIncome.setIncomeUserId(daoId);
            mallOrderIncome.setIncomeNum(purchaserDaoRatioIncome);
            mallOrderIncome.setCancelIncomePrice(BigDecimal.ZERO);
            mallOrderIncome.setRealIncomePrice(purchaserDaoRatioIncome);
            mallOrderIncome.setIncomeType(IncomeTypeEnum.ECOLOGICAL_COMMODITY_INCOME_BUY);
            mallOrderIncome.setIncomeName(IncomeTypeEnum.ECOLOGICAL_COMMODITY_INCOME_BUY.getDescription());
            mallOrderIncome.setIncomeProportion(mallProfitTemplate.getPurchaserDaoRatio());
            mallOrderIncome.setIncomeStatus(MallOrderIncomeTypeEnum.WAITING_ACCOUNT);
            mallOrderIncome.setIsTeamIncome(Boolean.FALSE);
            mallOrderIncome.setIncomeHierarchy(IncomeHierarchyEnum.SPECIAL);
            mallOrderIncome.setIncomeHierarchyName(IncomeHierarchyEnum.SPECIAL.getDescription());
            mallOrderIncome.setIncomeCardinality(sumProfit);
            mallOrderIncome.setIsEfficient(Boolean.FALSE);
            mallOrderIncome.setRemark(StrUtil.format("购买人网体所属DAO分润-{}", purchaserDaoRatioIncome));
            mallOrderIncome.insert();
            distributedProfits = distributedProfits.add(purchaserDaoRatioIncome);
        }
        // 创建平台分润记录
        MallOrderIncome commodityIncome = new MallOrderIncome();
        commodityIncome.setOrderId(mallOrder.getId());
        commodityIncome.setIncomeUserId(mallProfitTemplate.getEcologicalCommodityIncomeDaoId());
        commodityIncome.setIncomeNum(ecologicalCommodityIncomeDaoIncome);
        commodityIncome.setCancelIncomePrice(BigDecimal.ZERO);
        commodityIncome.setRealIncomePrice(ecologicalCommodityIncomeDaoIncome);
        commodityIncome.setIncomeType(IncomeTypeEnum.ECOLOGICAL_COMMODITY_INCOME_PLATFORM);
        commodityIncome.setIncomeName(IncomeTypeEnum.ECOLOGICAL_COMMODITY_INCOME_PLATFORM.getDescription());
        commodityIncome.setIncomeProportion(mallProfitTemplate.getEcologicalCommodityIncomeDaoRatio());
        commodityIncome.setIncomeStatus(MallOrderIncomeTypeEnum.WAITING_ACCOUNT);
        commodityIncome.setIsTeamIncome(Boolean.FALSE);
        commodityIncome.setIncomeHierarchy(IncomeHierarchyEnum.SPECIAL);
        commodityIncome.setIncomeHierarchyName(IncomeHierarchyEnum.SPECIAL.getDescription());
        commodityIncome.setIncomeCardinality(sumProfit);
        commodityIncome.setIsEfficient(Boolean.FALSE);
        commodityIncome.setRemark(StrUtil.format("平台分润收益-{}", ecologicalCommodityIncomeDaoIncome));
        commodityIncome.insert();
        return distributedProfits;
    }


    /**
     * 闹闹商城收益
     *
     * @param mallOrder
     * @param mallProfitTemplate
     * @param sumProfit
     * @param distributedProfits
     */
    private void buildMallIncome(MallOrder mallOrder, MallProfitTemplate mallProfitTemplate, BigDecimal sumProfit, BigDecimal distributedProfits) {
        // 计算金额
        BigDecimal mallIncome = sumProfit.subtract(distributedProfits);
        if (BigDecimalUtils.greaterZero(mallIncome)) {
            // 查询出NONO商城ID
            String noNoDaoId = staticDataDao.getByType("noNo_dao_id").getValue();

            MallOrderIncome mallOrderIncome = new MallOrderIncome();
            mallOrderIncome.setOrderId(mallOrder.getId());
            mallOrderIncome.setIncomeUserId(Long.valueOf(noNoDaoId));
            mallOrderIncome.setIncomeNum(mallIncome);
            mallOrderIncome.setCancelIncomePrice(BigDecimal.ZERO);
            mallOrderIncome.setRealIncomePrice(mallIncome);
            mallOrderIncome.setIncomeType(IncomeTypeEnum.NONO_INCOME);
            mallOrderIncome.setIncomeName(IncomeTypeEnum.NONO_INCOME.getDescription());
            mallOrderIncome.setIncomeProportion(mallProfitTemplate.getMallIncome());
            mallOrderIncome.setIncomeStatus(MallOrderIncomeTypeEnum.WAITING_ACCOUNT);
            mallOrderIncome.setIsTeamIncome(Boolean.FALSE);
            mallOrderIncome.setIncomeHierarchy(IncomeHierarchyEnum.SPECIAL);
            mallOrderIncome.setIncomeHierarchyName(IncomeHierarchyEnum.SPECIAL.getDescription());
            mallOrderIncome.setIncomeCardinality(sumProfit);
            mallOrderIncome.setIsEfficient(Boolean.FALSE);
            mallOrderIncome.setRemark(StrUtil.format("闹闹商城收益-{}", noNoDaoId));
            mallOrderIncome.insert();
        }
    }


    @Override
    public List<MallOrderIncome> getSettlementIncomeList() {
        return mallOrderIncomeDao.getSettlementIncomeList();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void settlementIncome(MallOrderIncome mallOrderIncome) throws GlobalException {
        // todo: 有些是到dao钱包的
        Boolean afterSalesOrderExists = mallOrderRefundService.whetherTheAfterSalesOrderExists(mallOrderIncome.getOrderId());
        if (afterSalesOrderExists) {
            // 存在售后中售后单 无法结算收益
            return;
        }
        Long incomeUserId = mallOrderIncome.getIncomeUserId();
        UserInfo user = userInfoDao.getById(incomeUserId);
        Assert.isTrue(ObjectUtil.isNotNull(user), () -> new GlobalRunTimeException(ErrorCode.THE_TARGET_USER_DOES_NOT_EXIST));
        MallOrder order = mallOrderService.getById(mallOrderIncome.getOrderId());

        //收益金额等于0 直接修改为已到账
        if (mallOrderIncome.getRealIncomePrice().compareTo(BigDecimal.ZERO) == 0) {
            mallOrderIncome.setIncomeStatus(MallOrderIncomeTypeEnum.HAS_ARRIVED);
            mallOrderIncome.updateById();
            return;
        }

        //收益金额小于等于0 不处理
        if (mallOrderIncome.getRealIncomePrice().compareTo(BigDecimal.ZERO) < 1) {
            return;
        }
        //加钱
        UserWallet incomeUserWallet = userWalletDao.getByUserId(incomeUserId);
        Assert.isTrue(userWalletDao.addIncome(incomeUserId, mallOrderIncome.getRealIncomePrice()), () -> new GlobalRunTimeException(ErrorCode.FAILED_TO_ADD_MONEY));

        mallOrderIncome.setIncomeStatus(MallOrderIncomeTypeEnum.HAS_ARRIVED);
        mallOrderIncome.updateById();


        UserIncomeRecord userIncomeRecord = new UserIncomeRecord();
        userIncomeRecord.setAmount(mallOrderIncome.getRealIncomePrice());
        userIncomeRecord.setUserId(mallOrderIncome.getIncomeUserId());
        userIncomeRecord.setIncomeType(mallOrderIncome.getIncomeType());
        userIncomeRecord.setIncomeTypeName(mallOrderIncome.getIncomeName());
        userIncomeRecord.setIncomeHierarchy(mallOrderIncome.getIncomeHierarchy());
        userIncomeRecord.setIncomeHierarchyName(mallOrderIncome.getIncomeHierarchyName());
        userIncomeRecord.setOrderNo(order.getOrderNo());
        userIncomeRecord.setIncomeCardinality(mallOrderIncome.getIncomeCardinality());
        userIncomeRecord.setIncomeProportion(mallOrderIncome.getIncomeProportion().toPlainString());
        userIncomeRecord.setSourceUserId(order.getUserId());
        userIncomeRecord.setIncomeUserNum("0");
        userIncomeRecord.setWeightsNum("0");
        userIncomeRecord.insert();

        UserWalletDetail userWalletDetail = new UserWalletDetail();
        userWalletDetail.setUserId(mallOrderIncome.getIncomeUserId());

        WalletDetailTypeEnum type;
        if (mallOrderIncome.getIncomeType() == IncomeTypeEnum.IP_MALL_DIRECT_PURCHASE) {
            type = WalletDetailTypeEnum.IP_MALL_DIRECT_PURCHASE;
        } else if (mallOrderIncome.getIncomeType() == IncomeTypeEnum.IP_MALL_INTERIM_PURCHASE) {
            type = WalletDetailTypeEnum.IP_MALL_INTERIM_PURCHASE;
        } else if (mallOrderIncome.getIncomeType() == IncomeTypeEnum.IP_MALL_NETWORK_REVENUE) {
            type = WalletDetailTypeEnum.IP_MALL_NETWORK_REVENUE;
        } else if (mallOrderIncome.getIncomeType() == IncomeTypeEnum.COPYRIGHT_INCOME) {
            type = WalletDetailTypeEnum.COPYRIGHT;
            expenditureRecordService.insertRecord(mallOrderIncome.getIncomeUserId(), mallOrderIncome.getRealIncomePrice(), BigDecimal.ZERO, mallOrderIncome.getRealIncomePrice(), ExpenditureRecordTypeEnum.COPYRIGHT, incomeUserWallet.getBalance(), incomeUserWallet.getBalance().add(mallOrderIncome.getRealIncomePrice()), mallOrderIncome.getOrderId(), mallOrderIncome.getRemark());
        } else if (mallOrderIncome.getIncomeType() == IncomeTypeEnum.SUPPLY_CHAIN) {
            type = WalletDetailTypeEnum.SUPPLY_CHAIN;
            expenditureRecordService.insertRecord(mallOrderIncome.getIncomeUserId(), mallOrderIncome.getRealIncomePrice(), BigDecimal.ZERO, mallOrderIncome.getRealIncomePrice(), ExpenditureRecordTypeEnum.SUPPLY_CHAIN, incomeUserWallet.getBalance(), incomeUserWallet.getBalance().add(mallOrderIncome.getRealIncomePrice()), mallOrderIncome.getOrderId(), mallOrderIncome.getRemark());
        } else {
            type = WalletDetailTypeEnum.IP_MALL_CITY_SERVER;
        }
        userWalletDetail.setType(type);
        userWalletDetail.setAmount(mallOrderIncome.getRealIncomePrice());
        userWalletDetail.setCharge(BigDecimal.ZERO);
        userWalletDetail.setRealAmount(mallOrderIncome.getRealIncomePrice());
        userWalletDetail.setAfterBalance(incomeUserWallet.getBalance().add(mallOrderIncome.getRealIncomePrice()));
        userWalletDetail.setBeforeBalance(incomeUserWallet.getBalance());
        userWalletDetail.setIdentityNo(StrUtil.EMPTY);
        userWalletDetail.setIsAdd(Boolean.TRUE);
        userWalletDetail.setPhone(StrUtil.EMPTY);
        userWalletDetail.setRemark(StrUtil.EMPTY);
        userWalletDetail.setCardNo(StrUtil.EMPTY);
        userWalletDetail.setBankName(StrUtil.EMPTY);
        userWalletDetail.setName(StrUtil.EMPTY);
        userWalletDetail.setBalanceType(UserBalanceTypeEnum.BALANCE);
        userWalletDetailDao.insert(userWalletDetail);


    }

    /**
     * 结算收益
     *
     * @param mallOrderIncome
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void newSettlementIncome(MallOrderIncome mallOrderIncome) throws GlobalException {
        //收益金额等于0 直接修改为已到账
        if (mallOrderIncome.getRealIncomePrice().compareTo(BigDecimal.ZERO) == 0) {
            mallOrderIncome.setIncomeStatus(MallOrderIncomeTypeEnum.HAS_ARRIVED);
            mallOrderIncome.updateById();
            return;
        }
        //收益金额小于等于0 不处理
        if (mallOrderIncome.getRealIncomePrice().compareTo(BigDecimal.ZERO) < 1) {
            return;
        }
        // 分润所属ID
        Long incomeUserId = mallOrderIncome.getIncomeUserId();
        // 订单ID
        MallOrder order = mallOrderService.getById(mallOrderIncome.getOrderId());

        if (Objects.isNull(order)) {
            return;
        }

        // 判断是否为分润给dao账户的
        if (IncomeTypeEnum.isDaoIncome().contains(mallOrderIncome.getIncomeType())) {
            // 分润给企业账户
            mallDaoWalletService.addBalance(incomeUserId, mallOrderIncome.getRealIncomePrice(), null, BigDecimal.ZERO, MallDaoWalletTypeEnum.ORDER_DISTRIBUTION, MallDaoWalletTypeEnum.ORDER_DISTRIBUTION.getDescription());
        } else if (IncomeTypeEnum.META_INCOME_DIVIDE == mallOrderIncome.getIncomeType()) {
            // 全民瓜分
            carveUpPoolService.addMallOrderPrizeDrawActivityPoolAmountLog(order.getId(), mallOrderIncome.getRealIncomePrice());
        } else if (IncomeTypeEnum.META_INCOME_RANKING_LIST == mallOrderIncome.getIncomeType()) {
            // 排行榜
            mallRankingListPoolService.addAmount(mallOrderIncome.getRealIncomePrice());
        } else {
            // 分给个人
            //加钱
            UserWallet incomeUserWallet = userWalletDao.getByUserId(incomeUserId);
            Assert.isTrue(userWalletDao.addIncome(incomeUserId, mallOrderIncome.getRealIncomePrice()), () -> new GlobalRunTimeException(ErrorCode.FAILED_TO_ADD_MONEY));
            UserWalletDetail userWalletDetail = new UserWalletDetail();
            userWalletDetail.setUserId(mallOrderIncome.getIncomeUserId());

            WalletDetailTypeEnum type;
            if (mallOrderIncome.getIncomeType() == IncomeTypeEnum.IP_MALL_DIRECT_PURCHASE) {
                type = WalletDetailTypeEnum.IP_MALL_DIRECT_PURCHASE;
            } else if (mallOrderIncome.getIncomeType() == IncomeTypeEnum.IP_MALL_INTERIM_PURCHASE) {
                type = WalletDetailTypeEnum.IP_MALL_INTERIM_PURCHASE;
            } else if (mallOrderIncome.getIncomeType() == IncomeTypeEnum.IP_MALL_NETWORK_REVENUE) {
                type = WalletDetailTypeEnum.IP_MALL_NETWORK_REVENUE;
            } else if (mallOrderIncome.getIncomeType() == IncomeTypeEnum.COPYRIGHT_INCOME) {
                type = WalletDetailTypeEnum.COPYRIGHT;
                expenditureRecordService.insertRecord(mallOrderIncome.getIncomeUserId(), mallOrderIncome.getRealIncomePrice(), BigDecimal.ZERO, mallOrderIncome.getRealIncomePrice(), ExpenditureRecordTypeEnum.COPYRIGHT, incomeUserWallet.getBalance(), incomeUserWallet.getBalance().add(mallOrderIncome.getRealIncomePrice()), mallOrderIncome.getOrderId(), mallOrderIncome.getRemark());
            } else if (mallOrderIncome.getIncomeType() == IncomeTypeEnum.SUPPLY_CHAIN) {
                type = WalletDetailTypeEnum.SUPPLY_CHAIN;
                expenditureRecordService.insertRecord(mallOrderIncome.getIncomeUserId(), mallOrderIncome.getRealIncomePrice(), BigDecimal.ZERO, mallOrderIncome.getRealIncomePrice(), ExpenditureRecordTypeEnum.SUPPLY_CHAIN, incomeUserWallet.getBalance(), incomeUserWallet.getBalance().add(mallOrderIncome.getRealIncomePrice()), mallOrderIncome.getOrderId(), mallOrderIncome.getRemark());
            } else {
                type = WalletDetailTypeEnum.IP_MALL_CITY_SERVER;
            }
            userWalletDetail.setType(type);
            userWalletDetail.setAmount(mallOrderIncome.getRealIncomePrice());
            userWalletDetail.setCharge(BigDecimal.ZERO);
            userWalletDetail.setRealAmount(mallOrderIncome.getRealIncomePrice());
            userWalletDetail.setAfterBalance(incomeUserWallet.getBalance().add(mallOrderIncome.getRealIncomePrice()));
            userWalletDetail.setBeforeBalance(incomeUserWallet.getBalance());
            userWalletDetail.setIdentityNo(StrUtil.EMPTY);
            userWalletDetail.setIsAdd(Boolean.TRUE);
            userWalletDetail.setPhone(StrUtil.EMPTY);
            userWalletDetail.setRemark(StrUtil.EMPTY);
            userWalletDetail.setCardNo(StrUtil.EMPTY);
            userWalletDetail.setBankName(StrUtil.EMPTY);
            userWalletDetail.setName(StrUtil.EMPTY);
            userWalletDetail.setBalanceType(UserBalanceTypeEnum.BALANCE);
            userWalletDetailDao.insert(userWalletDetail);
        }
        mallOrderIncome.setIncomeStatus(MallOrderIncomeTypeEnum.HAS_ARRIVED);
        mallOrderIncome.updateById();
        MetaMapSettle mallOrderNo = metaMapSettleDao.getMallOrderNo(order.getOrderNo());
        UserIncomeRecord userIncomeRecord = new UserIncomeRecord();
        userIncomeRecord.setAmount(mallOrderIncome.getRealIncomePrice());
        userIncomeRecord.setUserId(mallOrderIncome.getIncomeUserId());
        userIncomeRecord.setIncomeType(mallOrderIncome.getIncomeType());
        userIncomeRecord.setIncomeTypeName("商城购买");
        userIncomeRecord.setIncomeHierarchy(mallOrderIncome.getIncomeHierarchy());
        userIncomeRecord.setIncomeHierarchyName(mallOrderIncome.getIncomeHierarchyName());
        userIncomeRecord.setOrderNo(order.getOrderNo());
        userIncomeRecord.setIncomeCardinality(mallOrderIncome.getIncomeCardinality());
        userIncomeRecord.setIncomeProportion(mallOrderIncome.getIncomeProportion().toPlainString());
        userIncomeRecord.setSourceUserId(order.getUserId());
        if (BeanUtil.isEmpty(mallOrderNo)) {
            userIncomeRecord.setDescribe("商城地图");
        } else {
            userIncomeRecord.setDescribe(mallOrderNo.getMetaMap());
        }
//        userIncomeRecord.setDescribe(mallOrderIncome.getRemark());
        userIncomeRecord.setIncomeUserNum("0");
        userIncomeRecord.setWeightsNum("0");
        userIncomeRecord.insert();
    }

    @Override
    public MallOrderIncome getOneByIncomeUserIdAndIncomeTypeAndOrderId(Long incomeUserId, IncomeTypeEnum incomeTypeEnum, Long orderId) {
        return mallOrderIncomeDao.getOneByIncomeUserIdAndIncomeTypeAndOrderId(incomeUserId, incomeTypeEnum, orderId);
    }

    @Override
    public List<MallOrderIncome> getListByOrderId(Long orderId) {
        return mallOrderIncomeDao.getListByOrderId(orderId);
    }

    /**
     * 获取微信小程序用户的待结算佣金
     *
     * @param wxMiniUserId
     * @return
     */
    @Override
    public BigDecimal getToBeSettledWxMiniUserCommission(Long wxMiniUserId) {
        return mallOrderIncomeDao.getToBeSettledWxMiniUserCommission(wxMiniUserId);
    }

//    @Override
//    public void getIpMallProductProfit(MallOrder order) {
//        //获取订单商品
//        List<MallOrderProduct> orderProdcutList = mallOrderProductService.getListByOrderId(order.getId());
//
//        for (MallOrderProduct mallOrderProduct : orderProdcutList) {
//            BigDecimal singleSalesPrice = mallOrderProduct.getProductSalesPrice().multiply(Convert.toBigDecimal(mallOrderProduct.getProductNum()));
//            BigDecimal singleCostPrice = mallOrderProduct.getProductCostPrice().multiply(Convert.toBigDecimal(mallOrderProduct.getProductNum()));
//            BigDecimal bigDecimal = singleSalesPrice.subtract(singleCostPrice).setScale(3, BigDecimal.ROUND_DOWN);
//            carveUpPoolService.addPrizeDrawActivityPoolAmountLog(order.getUserId(), bigDecimal, mallOrderProduct.getProductId(), mallOrderProduct.getActivityId(), order.getId(), PrizeDrawActivityPoolBonusTaypEnum.IP_MALL);
//        }
//    }

}
